package main.java.com.waylau.netty.demo.telnet;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.net.InetAddress;
import java.util.Date;

/**
 * Handles a server-side channel.
 * 因为设置了编解码器 这里父类泛型中传入的是String类型的
 * Sharable 多个客户端共用一个Handler
 */
@Sharable
public class TelnetServerHandler extends SimpleChannelInboundHandler<String> {

    /**
     * @param ctx
     * @throws Exception
     * @描述 当客户端主动链接服务端的链接后，这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // Send greeting for a new connection.
        ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
        ctx.write("It is " + new Date() + " now.\r\n");
        ctx.flush();
    }

    /**
     * @param ctx
     * @throws Exception
     * @描述  当客户端主动断开服务端的链接后，这个通道就是不活跃的。
     *       也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }


    /**
	 * channelReadComplete
	 *
	 * channel  通道
	 * Read     读取
	 * Complete 完成
	 *
	 * 在通道读取完成后会在这个方法里通知，对应可以做刷新操作
	 * ctx.flush()
	 *
	 */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    /**
     * @param ctx
     * @param cause
     * @描述 服务端连接出现异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * channel 通道
     * Read    读
     *
     * I(泛型String) msg
     * I 枚举类型根据你继承的SimpleChannelInboundHandler<I>设置来的
     *
     * 同样你用channelRead也可以处理数据，但是作者已经提供了channelRead0，并且是抽象类
     *
     * 简而言之就是从通道中读取数据，也就是服务端接收客户端发来的数据
     * 但是这个数据在不进行解码时它是ByteBuf类型的后面例子我们在介绍
     */
    @Override
	protected void channelRead0(ChannelHandlerContext ctx, String request)
			throws Exception {
            // Generate and write a response.
            String response;
            boolean close = false;
            if (request.isEmpty()) {
                response = "Please type something.\r\n";
            } else if ("bye".equals(request.toLowerCase())) {
                response = "Have a good day!\r\n";
                close = true;
            } else {
                response = "Did you say '" + request + "'?\r\n";
            }

            // We do not need to write a ChannelBuffer here.
            // We know the encoder inserted at TelnetPipelineFactory will do the conversion.
            ChannelFuture future = ctx.write(response);
            System.out.println("response:"+response);
            // Close the connection after sending 'Have a good day!'
            // if the client has sent 'bye'.
            if (close) {
                future.addListener(ChannelFutureListener.CLOSE);
            }

    }
}
